package com.yonyou.train.service;

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.reflect.TypeToken;
import com.yonyou.train.dao.ReleaseCourseDao;
import com.yonyou.train.exception.ReleaseCourseException;
import com.yonyou.train.model.Class;
import com.yonyou.train.model.Class_Sub;
import com.yonyou.train.model.User;
import com.yonyou.train.util.index.SearcherUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;


import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class ReleaseCourseService {
    @Autowired
    private ReleaseCourseDao releaseCourseDao;

    //1.1我要开课主页业务
    public List getCreatedClasses(/*int pageindex, int pagesize,*/ String token) {
        if ("".equals(token) || token == null) {
            throw new ReleaseCourseException("用户非法");
        }
        List data = new ArrayList();
        //查询该讲师或助教所有主课程并按照时间排序
        List<Class> classes = releaseCourseDao.findClassesById(/*pageindex, pagesize, */Long.parseLong(token));
//遍历主课程
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd（E）HH:mm", Locale.CHINA);
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        for (Class clas : classes) {
            Map map = new HashMap();
            //获取主课程讲师和助教的头像
            List<Map> pic = releaseCourseDao.getImg(clas.getTeacher_id(), clas.getAssistant_id());

            map.put("teacherimg", pic.get(0).get("avatar"));
            map.put("assistantimg", pic.get(1).get("avatar"));

            //通过主课程id所有主课程
            List<Class_Sub> cs = releaseCourseDao.getSubClasses(clas.getId());
            List<Map> list = new ArrayList<Map>();
            for (Class_Sub sc : cs) {
                Map m = new HashMap();
                m.put("time", sdf.format(sc.getStarttime()).replaceAll("星期", "周") + "-" + df.format(sc.getEndtime()));
                m.put("address", sc.getAddress());
                m.put("subclassid", sc.getId());
                list.add(m);
            }
            map.put("subclassinfo", list);
            map.put("classid", clas.getId());
            map.put("teacher", clas.getTeacher_name());
            map.put("assistant", clas.getAssistant_name());
            map.put("teacherid", clas.getTeacher_id());
            map.put("assistantid", clas.getAssistant_id());
            map.put("subject", clas.getSubject());
            map.put("filepath", clas.getFilepath());
            data.add(map);
        }
        return data;
    }


    //2.1创建课程业务类
    public void createClass(Map<String, Object> map) {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();
        //获取子课程集合
        String s = gson.toJson(map.get("subclass"));
        List<Class_Sub> subclasses = null;
        Class clas = null;
        try {
            subclasses = gson.fromJson(s, new TypeToken<List<Class_Sub>>() {//对于不是类的情况，用这个参数给出
            }.getType());
            clas = gson.fromJson(gson.toJson(map.get("class")), Class.class);
        } catch (Exception e) {
            throw new ReleaseCourseException("缺少开课时间");
        }
        if (clas.getSubject() == null || "".equals(clas.getSubject()))
            throw new ReleaseCourseException("缺少课程名");
        if(subclasses.size()==0)
            throw new ReleaseCourseException("至少保留一门子课程");
        for (Class_Sub subcalss : subclasses) {
            if (subcalss.getAddress() == null || "".equals(subcalss.getAddress()))
                throw new ReleaseCourseException("缺少课程地点");
        }

        //判断时间逻辑
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (Class_Sub cs : subclasses) {
            if (cs.getEndtime().getTime() < cs.getStarttime().getTime())
                throw new ReleaseCourseException("子课程结束时间不能小于开始时间");
            if (cs.getStarttime().getTime() < new Date().getTime())
                throw new ReleaseCourseException("子课程开始时间不能小于当前系统时间");
            if (!sdf.format(cs.getStarttime()).equals(sdf.format(cs.getEndtime()))) {
                throw new ReleaseCourseException("子课程开始和结束时间必须在同一天");
            }
        }

        //向数据库中插入该课程
        releaseCourseDao.addClass(clas);

        //赋予子课程缺失值class_id
        for (Class_Sub cs : subclasses) {
            cs.setClass_id(clas.getId());
        }
        //向数据库中插入所有子课程
        releaseCourseDao.addSubClasses(subclasses);
    }


    //3.1查询需要的人
    public List getUsers(/*int pageindex, int pagesize, */String type, String search) {
        if (!("teachers".equals(type) || "allusers".equals(type))) {
            throw new ReleaseCourseException("传入搜索类型有误");
        }
        List<User> allteachers = new ArrayList<User>();
        if (search != null && search.matches("[a-zA-Z]+")) {
            List<String> names;
            if ((names = SearcherUtil.getNames(search.toLowerCase())).size() != 0)
                allteachers = releaseCourseDao.findAllUsersByPY(/*pageindex, pagesize, */type, names);
        } else {
            allteachers = releaseCourseDao.findAllUsers(/*pageindex, pagesize, */type, search);
        }
        List<Map> data = new ArrayList();
        for (User user : allteachers) {
            Map map = new HashMap();
            map.put("teacherid", user.getId());
            map.put("teachername", user.getName());
            map.put("dept", user.getDept_name());
            map.put("pic", user.getAvatar());
            data.add(map);
        }
        return data;
    }

    //4.1获取课程详情
    public Map getClassDetails(String classid) {
        Map map = new HashMap();
        //根据主课程id获取对应主课程
        Class someclass = releaseCourseDao.getClassById(Long.parseLong(classid));
        if (someclass == null) {
            throw new ReleaseCourseException("主课程不存在");
        }
        List<Map> pic = releaseCourseDao.getImg(someclass.getTeacher_id(), someclass.getAssistant_id());

        map.put("teacherimg", pic.get(0).get("avatar"));
        map.put("assistantimg", pic.get(1).get("avatar"));
        map.put("subject", someclass.getSubject());
        map.put("teacher", someclass.getTeacher_name());
        map.put("assistant", someclass.getAssistant_name());
        map.put("teacherid", someclass.getTeacher_id());
        map.put("assistantid", someclass.getAssistant_id());
        map.put("filepath", someclass.getFilepath());
        //根据主课程id查询所有子课程
        List<Class_Sub> subclasses = releaseCourseDao.getSubClasses(Long.parseLong(classid));
        List subclassesinfo = new ArrayList();
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd（E）HH:mm", Locale.CHINA);
        SimpleDateFormat df = new SimpleDateFormat("HH:mm");
        for (Class_Sub class_sub : subclasses) {
            HashMap m = new HashMap();
            m.put("subclassid", class_sub.getId());
            m.put("address", class_sub.getAddress());
            m.put("time", sdf.format(class_sub.getStarttime()).replaceAll("星期", "周") + "-" + df.format(class_sub.getEndtime()));
            subclassesinfo.add(m);
        }
        map.put("subclassesinfo", subclassesinfo);
        return map;
    }

    //5.考勤状态细节
    public Map getAttDetails(String subclassid) {
        //判定子课程是否存在
        if (releaseCourseDao.findSubClassesBySubId(Long.parseLong(subclassid)) == null)
            throw new ReleaseCourseException("子课程不存在");
        Map data = new HashMap();
        //获取报名人数
        int applicants = releaseCourseDao.getClassMembers(Long.parseLong(subclassid));
        data.put("applicants", applicants);
//获取请假人数
        int leavers = releaseCourseDao.getLeavers(Long.parseLong(subclassid));
        data.put("leavers", leavers);
        //获取签到人数
        int signers = releaseCourseDao.getSigners(Long.parseLong(subclassid));
        data.put("signers", signers);
        //获取未签到人数
        int unsigners = applicants - signers;
        data.put("unsigners", unsigners);
        return data;
    }

    //6.取消课程
    public void dropSubClass(Map<String, Long> subclassid) {
        if ("".equals(subclassid.get("subclassid")) || subclassid.get("subclassid") == null)
            throw new ReleaseCourseException("要删除子课程已不存在");
        Class_Sub subclass = releaseCourseDao.findSubClassesBySubId(subclassid.get("subclassid"));
        if (subclass == null)
            throw new ReleaseCourseException("要删除的子课程已不存在");
        releaseCourseDao.dropClassStudentInfo(subclassid.get("subclassid"));
        releaseCourseDao.dropSubClassBySubId(subclassid.get("subclassid"));
    }

    //7.修改课程
    public void updateClass(Map<String, Object> map) {
        Gson gson = new GsonBuilder().setDateFormat("yyyy-MM-dd HH:mm").create();
        //获取更新后的主课程
        Class clas = null;
        List<Class_Sub> new_subclasses = null;
        try {
            clas = gson.fromJson(gson.toJson(map.get("class")), Class.class);
            //获取更新后的子课程信息集和
            new_subclasses = gson.fromJson(gson.toJson(map.get("subclass")).replaceAll("subclassid", "id"), new TypeToken<List<Class_Sub>>() {//对于不是类的情况，用这个参数给出
            }.getType());
        } catch (Exception e) {
            throw new ReleaseCourseException("缺少开课时间");
        }
        if (new_subclasses.size() == 0) {
            throw new ReleaseCourseException("至少保留一门子课程");
        }
        if (clas.getSubject() == null || "".equals(clas.getSubject()))
            throw new ReleaseCourseException("缺少课程名");
        for (Class_Sub subcalss : new_subclasses) {
            if (subcalss.getAddress() == null || "".equals(subcalss.getAddress()))
                throw new ReleaseCourseException("缺少课程地点");
        }
        for (Class_Sub cs : new_subclasses) {
            cs.setClass_id(clas.getId());
        }
        //根据主课程id获取数据库中其所有子课程集合
        List<Class_Sub> old_subbclasses = releaseCourseDao.getSubClasses(clas.getId());
        //判断前端传来的数据逻辑是否正常
        //1.0 判断被删除掉的课程是否符合规定
        boolean flag = true;
        for (Class_Sub old : old_subbclasses) {
            for (Class_Sub nw : new_subclasses) {
                if (old.getId() == nw.getId()) {
                    flag = false;
                    continue;
                }
            }
            if (flag) {
                if (old.getStarttime().getTime() < new Date().getTime())
                    throw new ReleaseCourseException("已上完或正在上的子课程不能被删除");
            }
            flag = true;
        }
        //2.0 判断修改课程是否符合逻辑
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        for (Class_Sub nw : new_subclasses) {
            if (nw.getStarttime().getTime() > nw.getEndtime().getTime())
                throw new ReleaseCourseException("上课开始时间不能大于结束时间");
            if (!sdf.format(nw.getStarttime()).equals(sdf.format(nw.getEndtime())))
                throw new ReleaseCourseException("上课时间和下课时间必须是同一天");
            for (Class_Sub old : old_subbclasses) {
                if (old.getId() == nw.getId()) {
                    if ((!old.equals(nw)) && old.getStarttime().getTime() < new Date().getTime()) {
                        throw new ReleaseCourseException("不可以修改已经上完或正在上的子课程");
                    }
                    if (old.getStarttime().getTime() > new Date().getTime() && nw.getStarttime().getTime() < new Date().getTime())
                        throw new ReleaseCourseException("上课开始时间不能小于现在时间");
                    continue;
                }
            }
        }

        List<Class_Sub> updata = new ArrayList<Class_Sub>();
        List<Class_Sub> deldate = new ArrayList<Class_Sub>();
        if (old_subbclasses.size() > 0) {//如果数据库中有至少一门子课程信息
//1.0 找出被删除的子课程打包到集合中一次性去除,同时找出被修改过的子课程集合打包，一次性修改
            for (Class_Sub old : old_subbclasses) {
                for (Class_Sub nw : new_subclasses) {
                    if (old.getId() == nw.getId()) {
                        if (!old.equals(nw))
                            //放入集合中
                            updata.add(nw);
                        flag = false;
                        continue;
                    }
                }
                if (flag)
                    deldate.add(old);
                flag = true;
            }
            //批量删除子课程信息
            //1.0批量删除子课程下辖的class_student表中的数据
            if (deldate.size() > 0) {
                List<Long> subclassids = new ArrayList<Long>();
                for (Class_Sub nw : deldate) {
                    subclassids.add(nw.getId());
                }
                releaseCourseDao.deleteAllClassStudents(subclassids);
                //2.0 批量删除子课程信息
                releaseCourseDao.deleteAllSubClasses(subclassids);
            }
            if (updata.size() > 0) {
                //批量更新子课程信息
                releaseCourseDao.updateSubClasses(updata);
            }
        } else if (old_subbclasses.size() == 0) {//如果只是更新,数据库中没有任何子课程
            if (new_subclasses.size() > 0)
                releaseCourseDao.addSubClasses(new_subclasses);
        }
        for (Class_Sub sc : old_subbclasses) {
            if (sc.getStarttime().getTime() > new Date().getTime()) {
                flag = false;
                continue;
            }
        }
        if (!flag) {
            releaseCourseDao.updateClass(clas);
        } else {
            throw new ReleaseCourseException("不能修改已经上完或正在上的课程");
        }
    }

    //8.查看人员考勤信息和请假信息
    public Object getUserInfo(/*int pageindex, int pagesize, */String subclassid, String type, String search) {
        if (subclassid == null || "".equals(subclassid))
            throw new ReleaseCourseException("传入子课程不存在");
        if (releaseCourseDao.findSubClassesBySubId(Long.parseLong(subclassid)) == null)
            throw new ReleaseCourseException("传入的子课程已不在");
        if (Integer.parseInt(type) == 0) {//查看考勤
            if (search != null && search.matches("[a-zA-Z]+")) {
                List<String> names;
                if ((names = SearcherUtil.getNames(search.toLowerCase())).size() != 0) {
                    return releaseCourseDao.findAttInfoByPY(Long.parseLong(subclassid), names);
                }
            } else {
                return releaseCourseDao.findAttInfo(/*pageindex, pagesize, */Long.parseLong(subclassid), search);
            }
        } else if (Integer.parseInt(type) == 1) {//查看请假
            if (search != null && search.matches("[a-zA-Z]+")) {
                List<String> names;
                if ((names = SearcherUtil.getNames(search.toLowerCase())).size() != 0) {
                    return releaseCourseDao.findLeaInfoByPY(Long.parseLong(subclassid), names);
                }
            } else {
                return releaseCourseDao.findLeaInfo(/*pageindex, pagesize, */Long.parseLong(subclassid), search);
            }
        } else {
            throw new ReleaseCourseException("查看类型出错");
        }
        return new ArrayList<Map>();
    }

    //9.修改请假状态
    public void updateLeaState(Map map) {
        List<Long> userids = (List<Long>) map.get("userids");
        long subclassid = (Integer) map.get("subclassid");
        if (userids.size() == 0)
            throw new ReleaseCourseException("未选中任何人员");
        if (releaseCourseDao.findStateOfSign(userids, subclassid) > 0)
            throw new ReleaseCourseException("已签到人员不能被选中");
        releaseCourseDao.updateLeaState(userids, subclassid);
    }

    //10.0删除课程
    public void dropCourse(Map<String, Long> map) {
        //获取课程id
        long classid = map.get("classid");
        //删除class_student表中相关数据
        releaseCourseDao.dropCourse_clastu(classid);
        //删除class_sub表中的相关数据
        releaseCourseDao.dropCourse_clasub(classid);
        //删除class表中的相关数据
        releaseCourseDao.dropCourse_class(classid);
    }
}
